package com.custom.action.joiner.interfaces;

import com.custom.comm.enums.DbJoinStyle;
import com.custom.comm.utils.lambda.SFunction;

/**
 * 表关联函数
 * @author Xiao-Bai
 * @since 2023/5/1 0:41
 * @param <Children> 子类
 */
public interface LambdaJoinFunc<Children> extends OnCondition<Children> {

    /**
     * 表关联方法
     * @param condition 是否关联
     * @param joinClass 本次关联的对象(表)
     * @param aColumn 本次待关联对象的字段
     * @param bColumn 已关联对象的字段
     * @param <A> 本次待关联对象
     * @param <B> 已关联的对象
     * @return
     */
    default <A, B> Children join(boolean condition, DbJoinStyle joinStyle, Class<A> joinClass, String joinAlias, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(condition, joinStyle, joinClass, joinAlias, e -> e.eq(aColumn, bColumn));
    }
    default <A, B> Children join(boolean condition, DbJoinStyle joinStyle, Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(condition, joinStyle, joinClass, e -> e.eq(aColumn, bColumn));
    }
    default <A> Children join(boolean condition, DbJoinStyle joinStyle, Class<A> joinClass, OnExpression expression) {
        return join(condition, joinStyle, joinClass, null, expression);
    }
    <A> Children join(boolean condition, DbJoinStyle joinStyle, Class<A> joinClass, String joinAlias, OnExpression expression);

    default <A, B> Children leftJoin(Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.LEFT, joinClass, aColumn, bColumn);
    }

    default <A, B> Children leftJoin(Class<A> joinClass, String joinAlias, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.LEFT, joinClass, joinAlias, aColumn, bColumn);
    }

    default <A, B> Children leftJoin(boolean condition, Class<A> joinClass, String joinAlias, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(condition, DbJoinStyle.LEFT, joinClass, joinAlias, aColumn, bColumn);
    }

    default <A> Children leftJoin(boolean condition, Class<A> joinClass, OnExpression expression) {
        return join(condition, DbJoinStyle.LEFT, joinClass, expression);
    }

    default <A> Children leftJoin(Class<A> joinClass, OnExpression expression) {
        return join(true, DbJoinStyle.LEFT, joinClass, expression);
    }

    default <A> Children leftJoin(Class<A> joinClass, String joinAlias, OnExpression expression) {
        return join(true, DbJoinStyle.LEFT, joinClass, joinAlias, expression);
    }

    default <A, B> Children rightJoin(Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.RIGHT, joinClass, aColumn, bColumn);
    }

    default <A, B> Children rightJoin(Class<A> joinClass, String joinAlias, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.RIGHT, joinClass, joinAlias, aColumn, bColumn);
    }

    default <A, B> Children rightJoin(boolean condition, Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(condition, DbJoinStyle.RIGHT, joinClass, aColumn, bColumn);
    }

    default <A> Children rightJoin(boolean condition, Class<A> joinClass, OnExpression expression) {
        return join(condition, DbJoinStyle.RIGHT, joinClass, expression);
    }

    default <A> Children rightJoin(Class<A> joinClass, OnExpression expression) {
        return join(true, DbJoinStyle.RIGHT, joinClass, expression);
    }

    default <A> Children rightJoin(Class<A> joinClass, String joinAlias, OnExpression expression) {
        return join(true, DbJoinStyle.RIGHT, joinClass, joinAlias, expression);
    }

    default <A, B> Children innerJoin(Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.INNER, joinClass, aColumn, bColumn);
    }

    default <A, B> Children innerJoin(Class<A> joinClass, String joinAlias, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(true, DbJoinStyle.INNER, joinClass, joinAlias, aColumn, bColumn);
    }

    default <A, B> Children innerJoin(boolean condition, Class<A> joinClass, SFunction<A, ?> aColumn, SFunction<B, ?> bColumn) {
        return join(condition, DbJoinStyle.INNER, joinClass, aColumn, bColumn);
    }

    default <A> Children innerJoin(boolean condition, Class<A> joinClass, OnExpression expression) {
        return join(condition, DbJoinStyle.INNER, joinClass, expression);
    }

    default <A> Children innerJoin(Class<A> joinClass, OnExpression expression) {
        return join(true, DbJoinStyle.INNER, joinClass, expression);
    }

    default <A> Children innerJoin(Class<A> joinClass, String joinAlias, OnExpression expression) {
        return join(true, DbJoinStyle.INNER, joinClass, joinAlias, expression);
    }

}
